Skip to content

v0.4.14 — surface source_excerpt + meeting_date in read responses#21

Merged
jinhongkuan merged 1 commit into
mainfrom
chore/bump-v0.4.14
Apr 15, 2026
Merged

v0.4.14 — surface source_excerpt + meeting_date in read responses#21
jinhongkuan merged 1 commit into
mainfrom
chore/bump-v0.4.14

Conversation

@jinhongkuan

@jinhongkuan jinhongkuan commented Apr 15, 2026

Copy link
Copy Markdown
Contributor

Summary

The "tie meeting context to code" value prop only worked at write time. At read time, brief / drift / search returned the decision text and the source_ref string but stripped the raw source passage — even though `source_span.text` was sitting in the ledger waiting to be surfaced. Surfaced during demo gallery work when the visual was forced to either invent context or look thin.

Changes

  • `DecisionMatch`, `DriftEntry`, `BriefDecision` all gained `source_excerpt: str` + `meeting_date: str` fields
  • `search_by_bm25` pulls source_span via `<-yields<-source_span` reverse traversal in the same query — no extra DB roundtrip
  • `get_decisions_for_file` does a single follow-up batched query against matched intent IDs to backfill the same fields
  • Synthetic-span filter: `_reground_ungrounded` writes placeholder source_spans where `text == intent.description` to trigger lazy grounding. Both query paths filter those out so the excerpt always reflects the original meeting passage, never the bookkeeping placeholder
  • Test isolation fixes for v0.4.13 dedup tests that were sharing state with v0.4.14 tests via the in-memory ledger singleton

Test plan

  • 4 new cases in `tests/test_v0414_source_excerpt.py` (search/brief/drift/empty)
  • Full v0.4.14 regression: 215 passed

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added source_excerpt and meeting_date fields to decision responses in search results, briefs, and drift detection, providing richer context for each decision match.
  • Tests

    • Added comprehensive test coverage validating the new fields across search, brief, and drift detection flows.
  • Chores

    • Version bumped to 0.4.14.

The "tie meeting context to code" value prop only worked at write
time. At read time, brief / drift / search returned the decision
text and source_ref string but stripped the raw source passage that
produced the decision — even though source_span.text was sitting in
the ledger waiting to be surfaced. Surfaced during demo gallery work
when the visual was forced to either invent meeting context or look
thin.

Added:

  - DecisionMatch.source_excerpt + meeting_date (search responses)
  - DriftEntry.source_excerpt + meeting_date (drift responses)
  - BriefDecision.source_excerpt + meeting_date (brief responses)
  - search_by_bm25 pulls source_span.{text, meeting_date} via
    <-yields<-source_span reverse traversal in the same query — no
    extra DB roundtrip
  - get_decisions_for_file does a single follow-up batched query
    against matched intent IDs to backfill the same fields
  - Synthetic-span filter: _reground_ungrounded writes placeholder
    source_spans where text == intent.description to trigger lazy
    grounding. Both query paths filter those out so the excerpt
    reflects the original meeting passage, never the bookkeeping
    placeholder.

Tests:

  - 4 new cases in tests/test_v0414_source_excerpt.py covering
    search/brief/drift/empty paths
  - Test isolation fixes for v0.4.13 dedup tests that were sharing
    state with v0.4.14 tests via the in-memory ledger singleton

Full v0.4.14 regression: 215 passed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@jinhongkuan jinhongkuan merged commit 70b28a1 into main Apr 15, 2026
@jinhongkuan jinhongkuan deleted the chore/bump-v0.4.14 branch April 15, 2026 04:39
@coderabbitai

coderabbitai Bot commented Apr 15, 2026

Copy link
Copy Markdown

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d1ba082d-55e3-4f86-81a1-15548eb29480

📥 Commits

Reviewing files that changed from the base of the PR and between 33a6fba and dd36261.

📒 Files selected for processing (9)
  • CHANGELOG.md
  • contracts.py
  • handlers/brief.py
  • handlers/detect_drift.py
  • handlers/search_decisions.py
  • ledger/queries.py
  • pyproject.toml
  • tests/test_v0413_canonical_dedup.py
  • tests/test_v0414_source_excerpt.py

📝 Walkthrough

Walkthrough

The changes add source_excerpt and meeting_date fields to decision response models and thread them through read paths (search, brief, drift detection). Enhanced database queries retrieve source span text and meeting dates in a single roundtrip, with filtering to exclude synthetic placeholders. Comprehensive tests validate the feature across all read operations.

Changes

Cohort / File(s) Summary
Contract & Versioning
contracts.py, pyproject.toml
Added source_excerpt and meeting_date optional string fields (default "") to DecisionMatch, DriftEntry, and BriefDecision response models. Version bumped from 0.4.13 to 0.4.14.
Handler Integrations
handlers/brief.py, handlers/detect_drift.py, handlers/search_decisions.py
Each handler now populates source_excerpt and meeting_date on response objects by forwarding values from underlying decision data or query results, with empty-string defaults when absent.
Data Layer & Queries
ledger/queries.py
search_by_bm25 now fetches source_span.text and meeting_date via reverse yields edge in a single query and filters out empty/synthetic placeholder spans. get_decisions_for_file similarly enhanced with a batched follow-up query to backfill the same fields for all matched intent IDs, applying identical placeholder filtering.
Documentation
CHANGELOG.md
Added v0.4.14 changelog entry documenting the new source_excerpt and meeting_date fields, reverse traversal optimization, synthetic-span filtering, and test coverage.
Test Updates
tests/test_v0413_canonical_dedup.py, tests/test_v0414_source_excerpt.py
Added ledger singleton reset calls to existing tests for isolation. New comprehensive test file with four async phase2 tests validating excerpt/date presence across search, brief, and drift responses, plus empty source_span.text handling.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

Bouncing through the data streams so bright,
Source excerpts and dates now in sight!
No extra roundtrips slow the way,
Synthetic placeholders filtered away,
From search to brief, each query's right! 🐰✨

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/bump-v0.4.14

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

jinhongkuan pushed a commit that referenced this pull request Apr 30, 2026
v1 → v2: F-1 (BLOCKING razor) closed via Phase 0a decomposition.
F-2 (NON-BLOCKING OWASP A01/A05) and F-3 (truncation semantics)
also closed in same amendment.

Plan content hash: sha256:4b25a8f9...
Audit report hash: sha256:2bc161d2...
Chain hash: 86225d4919f2335322b43bfff8e8d9b63fb4bcd768f0c4ae90751dbcbabb1fd7

Next: /qor-implement.
jinhongkuan pushed a commit that referenced this pull request Apr 30, 2026
…hook

Phase 0a — Decompose server.py:cli_main (92 LOC → 15 LOC orchestrator
+ _register_subparsers (16 LOC) + _dispatch (29 LOC)). Razor-compliant.

Phase 0 — Promote cli/branch_scan.py:_invoke_link_commit to shared
cli/_link_commit_runner.py module. Pure refactor under existing
test_branch_scan_cli.py coverage.

Phase 1 — Register link_commit CLI subcommand:
- cli/link_commit_cli.py (29 LOC) — JSON-to-stdout default, --quiet
  flag, always exits 0 (graceful skip on no-ledger or handler error).
- server.py — subparser registration in _register_subparsers + dispatch
  branch in _dispatch.
- tests/test_link_commit_cli.py (6 tests) — argparse defaults, output
  shape, --quiet, no-ledger graceful skip, handler-exception graceful
  skip.

Phase 2 — Harden post-commit hook:
- setup_wizard.py:_GIT_POST_COMMIT_HOOK now writes stderr to
  ${HOME}/.bicameral/hook-errors.log (was /dev/null), surfaces a
  one-line summary on stderr, always exits 0. > truncates the file
  on each run so successful commits auto-clear stale errors. F-2
  remediation per audit v2.
- tests/test_hook_command_registration.py (3 tests) — smoke that
  walks every bicameral-mcp <cmd> in installed hooks and asserts
  CLI registration + dispatch coverage. Original #124 bug class is
  now caught at PR time.

Phase 3 — CHANGELOG [Unreleased] Fixed entry.

Validation: 20 passed, 1 skipped (Windows chmod). ruff check + format
+ mypy clean. Manual smoke: link_commit --help renders.

Plan v2 PASS at META_LEDGER #21 (chain 86225d49). Implementation
sealed at META_LEDGER #22 (chain e83d674c).

Closes #124.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
jinhongkuan pushed a commit that referenced this pull request Apr 30, 2026
Reality matches Promise. All 8 files (5 new + 4 modified - 1 plan)
land per v2 plan; 9 new tests + 11 regression = 20 passed, 1 skipped;
ruff/format/mypy clean; manual smoke confirms link_commit subcommand
registers and renders correctly.

Plan: plan-124-post-commit-hook-fix.md (v2 PASS @ 44c6568)
Audit: META_LEDGER #21 (chain hash 86225d49)
Implementation: META_LEDGER #22 (chain hash e83d674c)
Merkle seal: 950f362cb700da5a4db85c545f6b55bb725502a5744bfbb2c2eb3a9c9728661a

Closes #124 silent-failure regression. Defense-in-depth: the fix
itself, the cli_main decomposition (so the next subcommand addition
doesn't hit the same wall), the hook-command-registration smoke test
(catches this bug class at PR time), and the loud-but-non-blocking
hook (next regression surfaces immediately).

Capability shortfalls: gate artifacts, reliability sweep, version
bump all skipped (qor/ runtime helpers absent on this branch).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
jinhongkuan pushed a commit that referenced this pull request Apr 30, 2026
…hook

Phase 0a — Decompose server.py:cli_main (92 LOC → 15 LOC orchestrator
+ _register_subparsers (16 LOC) + _dispatch (29 LOC)). Razor-compliant.

Phase 0 — Promote cli/branch_scan.py:_invoke_link_commit to shared
cli/_link_commit_runner.py module. Pure refactor under existing
test_branch_scan_cli.py coverage.

Phase 1 — Register link_commit CLI subcommand:
- cli/link_commit_cli.py (29 LOC) — JSON-to-stdout default, --quiet
  flag, always exits 0 (graceful skip on no-ledger or handler error).
- server.py — subparser registration in _register_subparsers + dispatch
  branch in _dispatch.
- tests/test_link_commit_cli.py (6 tests) — argparse defaults, output
  shape, --quiet, no-ledger graceful skip, handler-exception graceful
  skip.

Phase 2 — Harden post-commit hook:
- setup_wizard.py:_GIT_POST_COMMIT_HOOK now writes stderr to
  ${HOME}/.bicameral/hook-errors.log (was /dev/null), surfaces a
  one-line summary on stderr, always exits 0. > truncates the file
  on each run so successful commits auto-clear stale errors. F-2
  remediation per audit v2.
- tests/test_hook_command_registration.py (3 tests) — smoke that
  walks every bicameral-mcp <cmd> in installed hooks and asserts
  CLI registration + dispatch coverage. Original #124 bug class is
  now caught at PR time.

Phase 3 — CHANGELOG [Unreleased] Fixed entry.

Validation: 20 passed, 1 skipped (Windows chmod). ruff check + format
+ mypy clean. Manual smoke: link_commit --help renders.

Plan v2 PASS at META_LEDGER #21 (chain 86225d49). Implementation
sealed at META_LEDGER #22 (chain e83d674c).

Closes #124.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
(cherry picked from commit 431e202)

Adaptation: server.py — kept dev's _register_subparsers / _dispatch helper extraction (#124 phase 0a refactor) so test_hook_command_registration.py introspection works; omitted dev's branch-scan subparser registration and the setup --with-push-hook flag (both are #48 prerequisites missing on triage)
Adaptation: server.py:_dispatch — kept dev's setup → branch-scan → link_commit dispatch chain shape; dropped branch-scan dispatch case (cli/branch_scan.py is a missing prerequisite from #48 on triage); kept link_commit dispatch case (the actual #124 fix)
Adaptation: tests/test_hook_command_registration.py — dropped _GIT_PRE_PUSH_HOOK import + the test_pre_push_hook_command_is_registered test (pre-push hook is from #48, not on triage); test_all_hook_commands_have_dispatch_branches scoped to _GIT_POST_COMMIT_HOOK only; test_post_commit_hook_command_is_registered (the canonical #124 regression test) is preserved
Skip: cli/branch_scan.py — kept triage's prior absence of this file (added by #48); the cherry-pick wanted to refactor it
Skip: docs/META_LEDGER.md — kept triage's HEAD chain state; e6d4b8f's META_LEDGER #21/#23 entries are dev's chain, not triage's
Skip: CHANGELOG.md — kept triage's HEAD; v0.X.Y triage release narrative goes in PR #128 per DEV_CYCLE §10.5.4
jinhongkuan pushed a commit that referenced this pull request Apr 30, 2026
…hook

Phase 0a — Decompose server.py:cli_main (92 LOC → 15 LOC orchestrator
+ _register_subparsers (16 LOC) + _dispatch (29 LOC)). Razor-compliant.

Phase 0 — Promote cli/branch_scan.py:_invoke_link_commit to shared
cli/_link_commit_runner.py module. Pure refactor under existing
test_branch_scan_cli.py coverage.

Phase 1 — Register link_commit CLI subcommand:
- cli/link_commit_cli.py (29 LOC) — JSON-to-stdout default, --quiet
  flag, always exits 0 (graceful skip on no-ledger or handler error).
- server.py — subparser registration in _register_subparsers + dispatch
  branch in _dispatch.
- tests/test_link_commit_cli.py (6 tests) — argparse defaults, output
  shape, --quiet, no-ledger graceful skip, handler-exception graceful
  skip.

Phase 2 — Harden post-commit hook:
- setup_wizard.py:_GIT_POST_COMMIT_HOOK now writes stderr to
  ${HOME}/.bicameral/hook-errors.log (was /dev/null), surfaces a
  one-line summary on stderr, always exits 0. > truncates the file
  on each run so successful commits auto-clear stale errors. F-2
  remediation per audit v2.
- tests/test_hook_command_registration.py (3 tests) — smoke that
  walks every bicameral-mcp <cmd> in installed hooks and asserts
  CLI registration + dispatch coverage. Original #124 bug class is
  now caught at PR time.

Phase 3 — CHANGELOG [Unreleased] Fixed entry.

Validation: 20 passed, 1 skipped (Windows chmod). ruff check + format
+ mypy clean. Manual smoke: link_commit --help renders.

Plan v2 PASS at META_LEDGER #21 (chain 86225d49). Implementation
sealed at META_LEDGER #22 (chain e83d674c).

Closes #124.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
(cherry picked from commit 431e202)

Adaptation: server.py — kept dev's _register_subparsers / _dispatch helper extraction (#124 phase 0a refactor) so test_hook_command_registration.py introspection works; omitted dev's branch-scan subparser registration and the setup --with-push-hook flag (both are #48 prerequisites missing on triage)
Adaptation: server.py:_dispatch — kept dev's setup → branch-scan → link_commit dispatch chain shape; dropped branch-scan dispatch case (cli/branch_scan.py is a missing prerequisite from #48 on triage); kept link_commit dispatch case (the actual #124 fix)
Adaptation: tests/test_hook_command_registration.py — dropped _GIT_PRE_PUSH_HOOK import + the test_pre_push_hook_command_is_registered test (pre-push hook is from #48, not on triage); test_all_hook_commands_have_dispatch_branches scoped to _GIT_POST_COMMIT_HOOK only; test_post_commit_hook_command_is_registered (the canonical #124 regression test) is preserved
Skip: cli/branch_scan.py — kept triage's prior absence of this file (added by #48); the cherry-pick wanted to refactor it
Skip: docs/META_LEDGER.md — kept triage's HEAD chain state; e6d4b8f's META_LEDGER #21/#23 entries are dev's chain, not triage's
Skip: CHANGELOG.md — kept triage's HEAD; v0.X.Y triage release narrative goes in PR #128 per DEV_CYCLE §10.5.4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant